<template>
  <div>Attr平台属性组件
    <el-card style="margin-bottom:20px">
        <categorySelector @changeCategoryId="changeCategoryId" ref="cs"/>
    </el-card>
    <el-card >          
          <!-- 表格：展示平台属性及数据列表界面 -->
          <div v-show="!isShowAddOrUpdateAttr">  
              <!-- 添加属性（大按钮） -->
            <el-button type="primary" icon="el-icon-plus" @click="showAddAttr" :disabled="!category3Id">添加属性</el-button>  
            <!-- 表格：展示平台属性的表格 -->
            <el-table  :data="attrList" border stripe style="width: 100%"  v-loading="loading">
                <el-table-column  type="index"   label="序号"  width="80" align="center">
                </el-table-column>
            <el-table-column   label="属性名称" style="width: 100%">
                <template slot-scope="{row}">
                    <el-badge :value="row.attrValueList.length" class="item">
                         <el-button size="small">{{row.attrName}}</el-button>
                    </el-badge>
                </template>  
            </el-table-column>
            <el-table-column  label="属性值列表" >
                <template slot-scope="{row}">
                    <!-- 遍历平台属性对象中的attrValueList数组 -->
                    <el-tag type="success" v-for="(val,index) in row.attrValueList" 
                    :key="val.id"
                    >{{val.valueName}}</el-tag>
                </template>  
            </el-table-column>
            <el-table-column   label="操作">
                <template slot-scope="{row}">
                         <HintButton title="修改属性" size="mini"  type="primary" icon="el-icon-edit"  @click="showUpdateAttr(row)"/>&nbsp;
                    <el-popconfirm :title="`您确定删除${row.attrName}吗？`" @onConfirm="deleteAttr(row.id)">
                         <HintButton title="删除属性" size="mini"  type="danger" icon="el-icon-delete" slot="reference" />
                    </el-popconfirm>
                    
                </template> 
            </el-table-column>
           </el-table>
          </div>
          <!-- 添加/修改平台属性和值的界面 -->
          <div v-show="isShowAddOrUpdateAttr">
              <el-form  inline >
                  <!-- 属性名称 -->
                  <el-form-item label="属性名称">
                      <el-input type="text" v-model="formData.attrName" placeholder="请输入属性名称" ></el-input>                    
                </el-form-item>
            </el-form>
                <!-- 添加/修改平台属性的两个按钮 -->
                <div style="margin-bottom:20px">                 
                    <el-button  type="primary" icon="el-icon-plus" @click="addAttrValue" :disabled="!formData.attrName.trim().length" >添加属性值</el-button>
                    <el-button @click="isShowAddOrUpdateAttr=false">取消</el-button>                
                </div>
                <!-- 添加/修改平台属性的表格 -->
                <el-table  :data="formData.attrValueList" border stripe style="width: 100%">
                    <el-table-column  type="index"   label="序号"  width="80" align="center"></el-table-column>
                    <el-table-column   label="属性值名称">
                        <template slot-scope="{row,$index}">
                            <!--  通过每一行的对象的edit属性作为标识，如果时true则显示文本框，否则显示span内容-->
                            <!--当查看模式时显示span,编辑模式时显示文本框  -->
                            <el-input  type="text" v-if="row.edit" v-model="row.valueName" placeholder="请输入属性值" 
                            size='mini' :ref="$index" @blur="toView(row)" @keyup.native.enter="toView(row)"></el-input>
                            <span type="success" v-else @click="toEdit(row,$index)" style="wideh:100%;display:inline-block">{{row.valueName}}</span>
                        </template>
                    </el-table-column>
                <el-table-column   label="操作" >
                    <template slot-scope="{row,$index}">                      
                        <el-popconfirm :title="`您确定删除${row.valueName}吗？`" @onConfirm="deleteValue($index)">
                         <HintButton  size="mini" type="danger" icon="el-icon-delete" title="删除属性值" slot="reference" />
                        </el-popconfirm>
                    </template> 
                </el-table-column>   
                </el-table>
                <!-- 添加/修改平台属性两个按钮 -->
                <div style="margin-bottom:20px">
                    <el-button type="primary" @click="save" :disabled="!isSaveValid">保存</el-button>
                    <el-button @click="isShowAddOrUpdateAttr=false">取消</el-button>
                </div>
            
          </div>
    </el-card>
  </div>
</template>

<script>
import categorySelector from '../categorySelector'
//引入深拷贝
import cloneDeep from 'lodash/cloneDeep'

  export default {
      name:'Attr',
      components:{
          categorySelector
      },
      data(){
           return{
             category1Id:'',//
             category2Id:'',
             category3Id:'',
             attrList:[],
             isShowAddOrUpdateAttr:false,//用来控制添加或修改平台属性值界面的标识
             loading:false, //加载页面
             //用来存储平台属性对象
             formData:{
                 //坑
             attrName:'',//平台属性名字
             attrValueList:[]//平台属性值数组
             },
           }
      },
      //计算属性 用来控制保存按钮的显示与禁用
      computed:{
          isSaveValid(){
              //属性名字是否有值，属性值列表中的属性值对象是否有数据
              return this.formData.attrName.trim()&& this.formData.attrValueList.some(attr=>attr.valueName.trim())
          }
      },

      //watch监视 对添加或修改平台属性的界面进行标识 进行监视
      watch:{
          isShowAddOrUpdateAttr(val){
              this.$refs.cs.isDisabled = val
          }
      },
       methods: {
          //获取平台属性数据
        async getAttrList(){             
              const result = await this.$API.attr.getAttrInfoList(this.category1Id,this.category2Id,this.category3Id)
                  if(result.code==200){
                      //更新下数据
                      this.attrList = result.data
                  }
          },
        //选中的分类内容改变的时候，所分发的自定义事件对应的回调函数
        //谁接收数据谁用@绑定自定义事件
        changeCategoryId({level,categoryId}){
        //一级分类的id，二级分类的id和三级分类id，保存起来，需要在三级分类分id传过来后调用接口
                // console.log(level,categoryId) 
                if(level==1){
                    this.category1Id = categoryId
                    //重置二，三级分类的id和平台属性数组
                    this.category2Id = null
                    this.category3Id = null
                    this.attrList = []
                }else if(level==2){
                    this.category2Id = categoryId
                    //重置三级分类id和平台属性数组
                    this.category3Id = null
                }else{                    
                    this.category3Id = categoryId
                    this.loading = false //获取平台属性时设置加载效果
                    this.getAttrList()
                }
        },          
        //点击修改属性按钮，显示修改平台属性界面
        showUpdateAttr(attrInfo){
        //    console.log(attrInfo)//测试点击修改按钮修改当前行属性信息（平台属性对象)
            //更新传过来的数据
            // this.formData = attrInfo
            //两个变量指向同一个空间地址因此用浅拷贝
            // this.formData = {...attrInfo}    
            //深拷贝
            this.formData = cloneDeep(attrInfo)
            //显示界面
            this.isShowAddOrUpdateAttr = true
        },
        //点击添加属性值按钮，为平台属性值对象数组arrValueList添加一个属性值对象
        addAttrValue(){
            this.formData.attrValueList.push({
                attrId: this.formData.id, //存储的时当前平添属性值对象所在的平台属性对象的id值（通过修改按钮获取到的）
                valueName:'',
                edit:true,//用来控制这一行的内容时编辑模式还是查看模式 
             })            
                //设置当前新的一行的文本框有焦点----默认光标
                //新添加的属性值的这一行的文本框的索引----就是arrValueList.length-1 
                // console.log(this.formData.attrValueList)
                //注意：$nextTick原因是因为将获取焦点事件延迟到下一次页面
                //v-if遍历完arrValueList数组对象的时候（此时已经创建了input标签）
                //如果不用$nextTick，当点击添加属性按钮是v-if还未遍历到arrValueList中有edit属性的时候
                //input标签还未创建，因此使用.focus方法会报错。
                this.$nextTick(()=>{
                    this.$refs[this.formData.attrValueList.length - 1].focus()
                })                
        },
        //查看模式
        toView(attrValue){
             console.log(attrValue.valueName.trim(),attrValue.valueName.trim()==='')
        // 判断文本框中是否有数据,此时没有数据,则不会变成查看模式
            if(attrValue.valueName.trim()==='') return     
        // let isKong = this.formData.attrValueList.filter(item =>item.valueName=='').length===1
        // if(isKong) return 
        // this.$message.warning('请输入内容')
        // 此时有数据,但是新录入的数据和之前已经存在的数据不能一样
             const isRepeat=this.formData.attrValueList.filter(val=>val.valueName===attrValue.valueName).length===2
                if(isRepeat){
                    // 此时说明新录入的数据和数组中已经存在的数据是一样的,这是不允许的
                    this.$message.warning('您输入了重复的数据,请重新输入')
                    attrValue.valueName='' // 直接清空重复的数据                    
                    return
                }      
                // 此时说明,数据存在,并且有效,变成查看模式
                attrValue.edit = false
                // console.log(attrValue.edit)
        },
        //编辑模式
        toEdit(attrValue,index){
            //判断当前的这一行的对象的标识是否存在，如果不存在那就说明此时的属性值对象没有edit属性，那么就添加一个
            if(!attrValue.hasOwnProperty('edit')){
                //添加的这个属性也要保证是响应式的
                this.$set(attrValue,'edit',true)
            }else{
                //此时有edit属性---此时这个属性是后添加的
                attrValue.edit = true;
            }
            //如果变成编辑模式。此时这一行出了文本框了，那么为了用户体验，设置文本框有有焦点
            this.$nextTick(()=>{
                this.$refs[index].focus()
            })

        },
     //删除某个属性值操作
     deleteValue(index){
          this.formData.attrValueList.splice(index,1)
          this.$message.success('删除成功')
     },
     //保存属性值操作
     async save(){
          //如果属性名字不存在，那么就不做修改操作
          if(this.formData.attrName.trim().length === 0) return
          //针对属性值对象数组中的数据过滤操作
           if (this.formData.attrValueList.find((attrValue) => attrValue.edit)) {
              this.$message.warning('请完成输入后再进行保存！！！')
              return
            }
          this.formData.attrValueList = this.formData.attrValueList.filter((attrValue)=>{
              //移出编辑或者查看模式的标识的属性
              delete attrValue.edit //删除自定义的标识属性（后台的数据中没有这个属性）
              //如果属性值为空直接返回
              return !!attrValue.valueName.trim()//直接就是布尔类型的值
              //return attrValue.valueName.trim() 也可以这样写，字符串直接转换成布尔类型的值
          })
          //再次筛选一下
          if(this.formData.attrValueList.length===0){
            this.$message.warning('至少添加一个属性值')
            return
          }
          //属性名字要存在属性值的数组重要有数据，至少有一个属性，属性值不能重复
          //调用接口
          const result = await this.$API.attr.addOrUpdateAttrInfo(this.formData)
          if(result.code !==200){
              //失败===提示用户
              this.$message.error('操作失败')
              return
          }
          //成功----提示用户，关闭当前的界面，页面的更新
          this.$message.success('操作成功')
          this.isShowAddOrUpdateAttr = false ;//关闭当前的界面
          this.getAttrList()//刷新
          
     },
     //删除平台属性
     async deleteAttr(attrId){
         const result = await this.$API.attr.deleteAttrInfoById(attrId)
         if(result.code !== 200){
             this.$message.error('操作失败')
             return
         }
         //提示
         this.$message.success('操作成功')
         //刷新
         this.getAttrList();
     },
      //点击添加属性按钮，显示添加属性界面
         showAddAttr(){
             this.formData={
                 attrName:'',//属性名字
                 attrValueList:[],//属性值最想数组
                 categoryId:this.category3Id,//三级分类id
                 categoryLevel:3,//级别就是3
             }
            this.isShowAddOrUpdateAttr = true
         },

   },
  }
</script>

<style scoped>
  .item {
  margin-top: 10px;
  margin-right: 40px;
}
</style>